package com.zsr.system.service.zfb.impl;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransUniTransferModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransUniTransferRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayFundTransUniTransferResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.zsr.common.enums.ZfbPayStatusEnum;
import com.zsr.common.utils.DateUtils;
import com.zsr.system.service.system.ISysConfigService;
import com.zsr.system.service.zfb.IAliPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
public class AliPayServiceImpl implements IAliPayService {
    /**
     * 支付宝应用ID
     */
    private final String APP_ID = "2021004159653889";


    /**
     * 商家ID
     */
    private final String SELLER_ID = "2088802419120676";


    /**
     * 应用私钥
     */
    private final String PRIVATE_KEY = "MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQDYkicx4PvsgrR7GfTMhEhfKq7pMlw3BEwBTAMUoesuYMfwb6x4/7ceNlbPekEKS+n2dfUzjJJ2jMNoC0DKuzsJSkEJJsJtxpGWDG2LyjntApHjbE9UywyPi6YBViqTWmg00B+yMuK14UeuHx5xJXlZ4gN3TGLb7sr6uen8/mp5IZ/w42mwKPIJJA7V0ieLjIXKJA9dZIhShg7LtRu89jbdPkfPQRom7o/t40C+CuEtFAWaNYbKcrqC558rCtOlaSZwd7QpbBOotL/nVi2c0ClnCrGUsIZQNhMUZ5iw/fBzTy2C4c5Yv/bot3/1UiXZAMS3xBGHBGAgtM9Sr1IWb9LlAgMBAAECggEBAIPgA3Pw/xaWxJXNSW6cAoHIuPeRTevGdw23Ho0ax93W2wkCx3BqrjP8fMIcPKyra01DqMr6B1me/4JEj/CjMCDJEW8kJfK4noBTEwWzX7B+Bx4IHwqQFhb2v2BC+uv9ekTmktZs+/Yqtv5FPsFBQ3LDGL81SWGJOBqSyPPgbC9Tdm5eJkL9f2CZe7417gEXttKyxQgyUGE1S5L4ksaeTPoNouSAdC+cL72WZB67YbvuIOeUN9nI5rSE/9ufth6NZ2c/8mPaEgcv/fkOozCZGFrlXRXzMgWYd3CDaO4ywmmouQC9zyT/pTkGZ0jeOKKEm3OQUoL+kplRDPHVQ6ZSHiUCgYEA8t1boVQSKsT1i2kiNcyhV19yIUmPnucMnsoE+snn+D4v3aWk3e0lKxNYI4aj/7LjaQOmfEdAotOhfheV5toLI/dWys+ZxghS+JJyd8hwx0MElth+7oC62PAyxkEdYXiCiY+qsxyLDLdfRyZHKblqN+s+kdqZczy6Q71E5FfrsOsCgYEA5Ei9B2ECwUzCY0ZkcHwvpfMcXjQ35y8f+6HFcNBbXGQCbpaDmp7r/mcMZvYjxXfAy1rPODMRjYyzDvZzhZIAb4J6sMkSiVqm1Yv2ywXf6bNkgAFgdEKmz1BhYjKhKzf6QK0gihlWKXIoKnGrqzhcZiQ7606tDYsNDPQ4bYDLF28CgYEAoWeRtRctd7UsRvmZHc4gT/QD4rGDvKRrU8CJLK8w9l9F6nViq4cmk4koo3ug1Jfr4OfnJmMoRs6FXkqIekLg8oc37FOqK91uXvrdDlRs91DH5QR+3z04cGK6K94si5HOl2Oem6jVlJ7tuFhtJQKv3/f8vmxcXSS32bsY5PS1k/8CgYEArX0SG1+AhoLdYDEI9+uJEqc1seohahKITeXddSUDqa1fo8fDcGjClO6foEgDW3jtDh6PSPiWqGp7Ui2+EY6pwhT5RQ0qhzRbggMCpbxrNOJeyGFDeleFChzeRZCQp5W9HBX2mr0ynADjwY3tlwwYPI/g8a0zGw3H90ZK8/1jWwUCgYEAjsVuOXwx646GdJY7aOdhBI3ez2MGsiLEj8TDbWj6g+WqWtUbXznKSskXorWfudjmb7ZO/piv+VxAYkb97xnQoKKdpkVXRZIdsBtJprW802eKS2nTCCiUJXl19TRGGpFBQGkpZJQ8tyDyneUIqwb3m4Hl2+2cdU5xGNWvx5u4AFY=";

    /**
     * 应用公钥
     */
    private final String APPLICATION_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2JInMeD77IK0exn0zIRIXyqu6TJcNwRMAUwDFKHrLmDH8G+seP+3HjZWz3pBCkvp9nX1M4ySdozDaAtAyrs7CUpBCSbCbcaRlgxti8o57QKR42xPVMsMj4umAVYqk1poNNAfsjLiteFHrh8ecSV5WeIDd0xi2+7K+rnp/P5qeSGf8ONpsCjyCSQO1dIni4yFyiQPXWSIUoYOy7UbvPY23T5Hz0EaJu6P7eNAvgrhLRQFmjWGynK6guefKwrTpWkmcHe0KWwTqLS/51YtnNApZwqxlLCGUDYTFGeYsP3wc08tguHOWL/26Ld/9VIl2QDEt8QRhwRgILTPUq9SFm/S5QIDAQAB";

    /**
     * 支付宝公钥
     */
    private final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2q/JbLtHSy6L86b1vhiiP/RoeIhe8ANkF4OWNL5/i/donLj5KRnT9Z0YwYwkS2zneWH+xRSf6UJECzDHTavvnnuTpUD1G/xvMSurN87+OkrNjCnxAymtK2V6od1QDY+r+T4wUSqM+9CKobi3Ys5I5/PfxVT5bWigqH2JMw4nXsqGzqPQSzp9bB6UnZ2TmtrgttY9LVWl/23KOZ4tcjP7abl5FCa5NwB2gtsp+S5dSjb0YDmFVNcvliPR91zBN6HS+TPcVBTzDa5btG97ANH9TrzU8ot9RKk7XNZHNendIhh4wxRiCiPwGs2CUlizYLMWAaBDrsll3e0HzIEjy185CwIDAQAB";

    /**
     * 请求参数格式
     */
    private final String FORMAT = "json";

    /**
     * 请求编码
     */
    private final String CHARSET = "UTF-8";

    /**
     * 签名类型
     */
    private final String SIGN_TYPE = "RSA2";


    @Resource
    private ISysConfigService sysConfigService;

    @Override
    public String phoneAliPay(String orderId, BigDecimal amount, String title, Date expireTime) {

        // 用户中途退出付款返回的系统地址
        String quit_url = "https://system.ikfkids.com/point/mall/mineOrder?flag=0";

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        //  异步接收地址，仅支持http/https，公网可访问。用于接收该接口异步通知信息、处理解析返回的数据并保存到  数据库。接口必须为post请求，
        request.setNotifyUrl(sysConfigService.selectConfigByKey("zfb.notify.url"));
        //  同步跳转地址，仅支持http/https，返回的前端界面跳转，比如支付成功返回界面。支付失败返回界面
        request.setReturnUrl("https://system.ikfkids.com/point/mall/finish?orderId=" + orderId);

        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", orderId);
        //支付金额，最小值0.01元
        bizContent.put("total_amount", amount);
        //订单标题，不可使用特殊符号
        bizContent.put("subject", title);
        // 用户中途退出返回的系统地址
        bizContent.put("quit_url", quit_url);

        /******可选参数******/
        //手机网站支付默认传值QUICK_WAP_WAY
        bizContent.put("product_code", "QUICK_WAP_WAY");
        // 设置未支付订单过期时间，在订单过期时间的基础上再往后延迟5秒
        Date date = DateUtils.updateDateBySecondReturnDate(expireTime, 3);
        bizContent.put("time_expire", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, date));

        request.setBizContent(bizContent.toString());
        AlipayTradeWapPayResponse response;
        try {
            response = alipayClient.pageExecute(request, "GET");
            log.info("支付宝手机网站支付回调结果：response:{}", JSONObject.toJSONString(response));
            if (response.isSuccess()) {
                log.info("支付宝手机网站支付成功");
                return response.getBody();
            } else {
                System.out.println("调用失败");
                log.info("response:{}", response);
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        return null;
    }


    @Override
    public String sandboxPay(String orderId, BigDecimal amount, String title, Date expireTime) {
        // 用户中途退出付款返回的系统地址
        String quit_url = "http://localhost/point/mall/mineOrder?flag=0";

        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi-sandbox.dl.alipaydev.com/gateway.do", APP_ID, PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
        //  异步接收地址，仅支持http/https，公网可访问。用于接收该接口异步通知信息、处理解析返回的数据并保存到数据库。接口必须为post请求，
        request.setNotifyUrl("http://localhost:8090/aliPay/notify");
        //  同步跳转地址，仅支持http/https，返回的前端界面跳转，比如支付成功返回界面。
        request.setReturnUrl("http://localhost/point/mall/finish?orderId=" + orderId);

        /******必传参数******/
        JSONObject bizContent = new JSONObject();
        //商户订单号，商家自定义，保持唯一性
        bizContent.put("out_trade_no", orderId);
        //支付金额，最小值0.01元
        bizContent.put("total_amount", amount);
        //订单标题，不可使用特殊符号
        bizContent.put("subject", title);
        // 用户中途退出返回的系统地址
        bizContent.put("quit_url", quit_url);


        /******可选参数******/
        //手机网站支付默认传值QUICK_WAP_WAY
        bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");
        // 设置未支付订单过期时间
        Date date = DateUtils.updateDateBySecondReturnDate(expireTime, 3);
        bizContent.put("time_expire", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, date));


        request.setBizContent(bizContent.toString());
        log.info("bizContent:{}", bizContent);
        log.info("request:{}", request);
        AlipayTradeWapPayResponse response;
        try {
            response = alipayClient.pageExecute(request, "GET");
            log.info("支付宝手机网站支付回调结果：response:{}", response);
            if (response.isSuccess()) {
                System.out.println("调用成功");
                return response.getBody();
            } else {
                System.out.println("调用失败");
                log.info("response:{}", response);
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    @Override
    public AlipayFundTransUniTransferResponse transfer(AlipayFundTransUniTransferModel model, AlipayConfig alipayConfig) {
        // 初始化SDK
        try {
            AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig);
            // 构造请求体
            AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
            request.setBizModel(model);
            return alipayClient.certificateExecute(request);
        } catch (AlipayApiException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String phonePayNotify(HttpServletRequest request) {
        log.info("=========支付宝异步回调========");
        Map<String, String> paramsMap = new HashMap<>();
        for (String name : request.getParameterMap().keySet()) {
            paramsMap.put(name, request.getParameter(name));
        }
        log.info("phonePayNotify~paramsMap:{}", paramsMap);
        // 支付宝验签
        boolean signVerified; //调用RSA验证签名
        try {
            signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
            log.info("signVerified:{}", signVerified);
        } catch (AlipayApiException e) {
            log.error("支付宝异步回调验签异常:{}", e.getErrCode());
            throw new RuntimeException(e);
        }
        if (!signVerified) {
            // 验签失败则记录异常日志，并返回failure.
            log.error("支付宝异步回调验签失败");
            return "failure";
        }

        log.info("该笔支付订单支付完成orderId：{}", paramsMap.get("out_trade_no"));
        log.info("交易名称: " + paramsMap.get("subject"));
        log.info("交易状态: " + paramsMap.get("trade_status"));
        log.info("支付宝交易凭证号: " + paramsMap.get("trade_no"));
        log.info("商户订单号: " + paramsMap.get("out_trade_no"));
        log.info("总交易金额: " + paramsMap.get("total_amount"));
        log.info("买家在支付宝唯一id: " + paramsMap.get("buyer_id"));
        log.info("买家付款时间: " + paramsMap.get("gmt_payment"));
        log.info("买家付款金额: " + paramsMap.get("buyer_pay_amount"));
        log.info("商家在收益中实际收到的款项: " + paramsMap.get("receipt_amount"));
        log.info("应用ID: " + paramsMap.get("app_id"));
        log.info("商家ID: " + paramsMap.get("seller_id"));


        String sellerId = paramsMap.get("seller_id"); // 商家Id
        String appId = paramsMap.get("app_id"); // 应用Id
        String orderId = paramsMap.get("out_trade_no"); // 订单Id
        String tradeStatus = paramsMap.get("trade_status"); // 订单Id
        BigDecimal zfbTotalAmount = new BigDecimal(paramsMap.get("total_amount")); // 订单总金额
        BigDecimal zfbReceiptAmount = new BigDecimal(paramsMap.get("receipt_amount")); // 卖家收到的金额
        Date payTime = DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, paramsMap.get("gmt_payment")); // 支付时间

        //  验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
//        if (dbOrder == null) {
//            log.info("该笔订单不存在orderId:{}", orderId);
//            return "failure";
//        }

        // 判断商家ID是否一致
        if (!Objects.equals(sellerId, SELLER_ID)) {
            log.info("该笔订单商家ID信息错误sellerId:{}", sellerId);
            return "failure";
        }

        // 判断应用ID是否一致
        if (!Objects.equals(appId, APP_ID)) {
            log.info("该笔订单应用ID信息错误appId:{}", appId);
            return "failure";
        }


        // 交易完成
        if (tradeStatus.equals(ZfbPayStatusEnum.TRADE_FINISHED.getValue())) {
            log.info("该笔支付订单交易完成orderId：{}", orderId);
            return "success";
        }

        // 交易关闭
        if (tradeStatus.equals(ZfbPayStatusEnum.TRADE_CLOSED.getValue())) {
            log.info("该笔支付订单交易关闭orderId：{}", orderId);

            // 业务操作，如果交易关闭则代表交易彻底完成，可以变更订单状态


            return "failure";
        }

        // 支付完成
        if (tradeStatus.equals(ZfbPayStatusEnum.TRADE_SUCCESS.getValue())) {
            // 业务操作，如果交易关闭则代表交易彻底完成，可以变更订单状态
            if (1 > 0) {
                return "success";
            }
            return "failure";
        }
        return "failure";
    }
}
